package com.app.web.socketio
import com.corundumstudio.socketio.SocketIOClient
import com.corundumstudio.socketio.SocketIOServer
import com.corundumstudio.socketio.annotation.OnConnect
import com.corundumstudio.socketio.annotation.OnDisconnect
import com.corundumstudio.socketio.protocol.Packet
import com.corundumstudio.socketio.protocol.PacketType
import groovy.transform.CompileStatic
import groovy.transform.TypeChecked
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.stereotype.Component

import javax.annotation.PostConstruct
import javax.annotation.PreDestroy

/**
 * 系统消息推送
 * Created by three on 14-9-29.
 */
@CompileStatic
@TypeChecked
@Component
class SystemMessageNotify {

    private static final String ROOM_NAME = "SYSMSG_ROOM";
    private static final String EVETN_NAME = "sys_msg";
    private static final List<Object> MSG_LIST = new LinkedList<Object>();
    private Thread sendThread = null;
    private boolean stop = false;

    @Autowired
    private SocketIOServer server;

    /**
     * 用户链接，加入系统推送列表
     * @param client
     */
    @OnConnect
    public void onConnectHandler(SocketIOClient client) {
        client.joinRoom(ROOM_NAME);
    }

    @OnDisconnect
    public void onDisconnectHandler(SocketIOClient client) {
        client.leaveRoom(ROOM_NAME);
    }

    @PreDestroy
    public void stop(){
        stop = true;
        if(null!=sendThread) {
            sendThread.interrupt();
        }
    }

    @PostConstruct
    public void listenMsg() {
        // 消息消费
        sendThread = new Thread(new Runnable() {
            @Override
            public void run() {
                while (!stop) {
                    try {
                        synchronized (ROOM_NAME) {
                            if(MSG_LIST.size()>0) {
                                Packet packet = new Packet(PacketType.MESSAGE);
                                packet.setSubType(PacketType.EVENT);
                                packet.setName(EVETN_NAME);
                                packet.setData(Arrays.asList(MSG_LIST.toArray()));
                                server.getRoomOperations(ROOM_NAME).send(packet);
                                MSG_LIST.clear();
                            }
                            ROOM_NAME.wait();
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
        });
        sendThread.start();

        // TODO 消息测试发送，正式环境需要去掉
        new Thread(new Runnable() {
            @Override
            void run() {
                while (true) {
                    Thread.sleep((int)(Math.random()*10000));
                    SystemMessageNotify.send(UUID.randomUUID().toString());
                }
            }
        }).start();
    }

    public static void send(Object msg) {
        synchronized (ROOM_NAME) {
            MSG_LIST.add(msg);
            try {
                ROOM_NAME.notifyAll();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}
